﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using DataLayer.EF;
using EntityLayer;

namespace DataLayer.CLASES_DAO
{
    public class clsT_OportunidadDAO
    {
        private BD_GESTIONVISITAEntities ContextoDeObjs = new BD_GESTIONVISITAEntities();
        public Boolean Insertar(T_Oportunidad obj)
        {
            try
            {
                ContextoDeObjs.AddObject("T_Oportunidad", obj);
                ContextoDeObjs.SaveChanges();
                return true;
            }
            catch (Exception)
            {
                ContextoDeObjs.Detach(obj);
                throw;
            }
        }
        public Boolean Modificar(T_Oportunidad obj)
        {
            try
            {
                ContextoDeObjs.AttachTo("T_Oportunidad", obj);
                ContextoDeObjs.ObjectStateManager.ChangeObjectState(obj, System.Data.EntityState.Modified);
                ContextoDeObjs.SaveChanges();
                return true;
            }
            catch (Exception)
            {
                throw;
            }
        }
        public Boolean Eliminar(T_Oportunidad obj)
        {
            try
            {
                ContextoDeObjs.AttachTo("T_Oportunidad", obj);
                ContextoDeObjs.DeleteObject(obj);
                ContextoDeObjs.SaveChanges();
                return true;
            }
            catch (Exception)
            {
                throw;
            }
        }
        public List<T_Oportunidad> listar(int? co_oportunidad = null)
        {
            List<T_Oportunidad> lista = new List<T_Oportunidad>();
            try
            {
                var q = from c in ContextoDeObjs.T_Oportunidad
                        select c;
                if (co_oportunidad != null) q = q.Where(f1 => f1.co_oportunidad == co_oportunidad);
                lista = q.ToList();
            }
            catch (Exception)
            {
                lista = null;
                throw;
            }
            return lista;
        }
        public IEnumerable<Object> GenerarListaOportunidades(int? co_servicio, int? co_producto, int? co_tipo_pres, Decimal? pres_ini, Decimal? pres_fin, Decimal? esf_ini, Decimal? esf_fin, int? co_tipo_esf, String no_sector, int? co_usuario)
        {
            IEnumerable<Object> lista = new List<Object>();
            try
            {
                Boolean ok = true;
                var q = (from cont in ContextoDeObjs.T_Contacto
                         join cli in ContextoDeObjs.T_Cliente on new { nu_ruc_cliente = cont.T_Cliente.nu_ruc } equals new { nu_ruc_cliente = cli.nu_ruc }
                         join conopor in ContextoDeObjs.T_Contacto_Oportunidad on cont.co_contacto equals conopor.co_contacto
                         join opor in ContextoDeObjs.T_Oportunidad on conopor.co_oportunidad equals opor.co_oportunidad
                         join oporpre in ContextoDeObjs.T_Oportunidad_Presupuesto on opor.co_oportunidad equals oporpre.co_oportunidad
                         join usu in ContextoDeObjs.T_Usuario on opor.co_usuario equals usu.co_usuario
                         join pre in ContextoDeObjs.T_Presupuesto on oporpre.co_presupuesto equals pre.co_presupuesto
                         join cliser in ContextoDeObjs.T_Cliente_Servicio on new { nu_ruc = cli.nu_ruc } equals new { nu_ruc = cliser.nu_ruc_cliente }
                         join ser in ContextoDeObjs.T_Servicio
                               on new { cliser.co_servicio, Column1 = opor.co_servicio }
                           equals new { ser.co_servicio, Column1 = ser.co_servicio }
                         join subser in ContextoDeObjs.T_SubServicio on ser.co_servicio equals subser.T_Servicio.co_servicio
                         join prod in ContextoDeObjs.T_Producto
                               on new { subser.co_subservicio, opor.co_producto }
                           equals new { prod.T_SubServicio.co_subservicio, prod.co_producto }
                         join oporestado in ContextoDeObjs.T_Oportunidad_Estado
                         on opor.co_opor_estado equals oporestado.co_opor_estado
                         where cli.no_sector_economico == no_sector && opor.co_opor_estado == 7 && usu.co_usuario == co_usuario
                         select new
                         {
                             cli.nu_ruc,
                             cli.no_razon_social,
                             co_servicio = (Int32?)ser.co_servicio,
                             ser.no_servicio,
                             co_producto = (Int32?)prod.co_producto,
                             prod.no_producto,
                             co_presupuesto = (Int32?)pre.co_presupuesto,
                             pre.qt_monto_base,
                             no_rubro_comercial = cli.no_principal_CIIU,
                             pre.co_tipo_moneda,
                             Moneda = pre.co_tipo_moneda == 0 ? "Dolares" : pre.co_tipo_moneda == 1 ? "Soles" : "",
                             Esfuerzo = (pre.co_tipo_esfuerzo == 1) ? pre.qt_esfuerzo / 30 : pre.qt_esfuerzo,
                             pre.co_tipo_esfuerzo,
                             Tiempo = pre.co_tipo_esfuerzo == 0 ? "Meses" : pre.co_tipo_esfuerzo == 1 ? "Meses" : "",
                             oporestado.no_opor_estado
                         }).Distinct();

                if (co_servicio != null) { q = q.Where(f1 => f1.co_servicio == co_servicio); ok = false; }
                if (co_producto != null) { q = q.Where(f1 => f1.co_producto == co_producto); ok = false; }
                if (pres_ini != null) { q = q.Where(f1 => f1.qt_monto_base >= pres_ini); ok = false; }
                if (pres_fin != null) { q = q.Where(f1 => f1.qt_monto_base <= pres_fin); ok = false; }
                if (co_tipo_pres != null) { q = q.Where(f1 => f1.co_tipo_moneda == co_tipo_pres); ok = false; }
                if (esf_ini != null) { q = q.Where(f1 => f1.Esfuerzo >= esf_ini); ok = false; }
                if (esf_fin != null) { q = q.Where(f1 => f1.Esfuerzo <= esf_fin); ok = false; }

                var s = (from cont in ContextoDeObjs.T_Contacto
                         join cli in ContextoDeObjs.T_Cliente on new { nu_ruc_cliente = cont.T_Cliente.nu_ruc } equals new { nu_ruc_cliente = cli.nu_ruc }
                         join conopor in ContextoDeObjs.T_Contacto_Oportunidad on cont.co_contacto equals conopor.co_contacto
                         join opor in ContextoDeObjs.T_Oportunidad on conopor.co_oportunidad equals opor.co_oportunidad
                         join oporpre in ContextoDeObjs.T_Oportunidad_Presupuesto on opor.co_oportunidad equals oporpre.co_oportunidad
                         join usu in ContextoDeObjs.T_Usuario on opor.co_usuario equals usu.co_usuario
                         join pre in ContextoDeObjs.T_Presupuesto on oporpre.co_presupuesto equals pre.co_presupuesto
                         join cliser in ContextoDeObjs.T_Cliente_Servicio on new { nu_ruc = cli.nu_ruc } equals new { nu_ruc = cliser.nu_ruc_cliente }
                         join ser in ContextoDeObjs.T_Servicio
                               on new { cliser.co_servicio, Column1 = opor.co_servicio }
                           equals new { ser.co_servicio, Column1 = ser.co_servicio }
                         join subser in ContextoDeObjs.T_SubServicio on ser.co_servicio equals subser.T_Servicio.co_servicio
                         join prod in ContextoDeObjs.T_Producto
                               on new { subser.co_subservicio, opor.co_producto }
                           equals new { prod.T_SubServicio.co_subservicio, prod.co_producto }
                         join oporestado in ContextoDeObjs.T_Oportunidad_Estado
                            on opor.co_opor_estado equals oporestado.co_opor_estado
                         where cli.no_sector_economico == no_sector && usu.co_usuario == co_usuario
                         select new
                         {
                             cli.nu_ruc,
                             cli.no_razon_social,
                             co_servicio = (Int32?)ser.co_servicio,
                             ser.no_servicio,
                             co_producto = (Int32?)prod.co_producto,
                             prod.no_producto,
                             co_presupuesto = (Int32?)pre.co_presupuesto,
                             pre.qt_monto_base,
                             no_rubro_comercial = cli.no_principal_CIIU,
                             pre.co_tipo_moneda,
                             Moneda = pre.co_tipo_moneda == 0 ? "Dolares" : pre.co_tipo_moneda == 1 ? "Soles" : "",
                             Esfuerzo = (pre.co_tipo_esfuerzo == 1) ? pre.qt_esfuerzo / 30 : pre.qt_esfuerzo,
                             pre.co_tipo_esfuerzo,
                             Tiempo = pre.co_tipo_esfuerzo == 0 ? "Meses" : pre.co_tipo_esfuerzo == 1 ? "Meses" : "",
                             oporestado.no_opor_estado
                         }).Distinct();

                if (co_servicio != null) { s = s.Where(f1 => f1.co_servicio == co_servicio); ok = false; }
                if (co_producto != null) { s = s.Where(f1 => f1.co_producto == co_producto); ok = false; }
                if (pres_ini != null) { s = s.Where(f1 => f1.qt_monto_base >= pres_ini); ok = false; }
                if (pres_fin != null) { s = s.Where(f1 => f1.qt_monto_base <= pres_fin); ok = false; }
                if (co_tipo_pres != null) { s = s.Where(f1 => f1.co_tipo_moneda == co_tipo_pres); ok = false; }
                if (esf_ini != null) { s = s.Where(f1 => f1.Esfuerzo >= esf_ini); ok = false; }
                if (esf_fin != null) { s = s.Where(f1 => f1.Esfuerzo <= esf_fin); ok = false; }


                var r = (from cont in ContextoDeObjs.T_Contacto
                         join cli in ContextoDeObjs.T_Cliente on new { nu_ruc_cliente = cont.T_Cliente.nu_ruc } equals new { nu_ruc_cliente = cli.nu_ruc }
                         join conopor in ContextoDeObjs.T_Contacto_Oportunidad on cont.co_contacto equals conopor.co_contacto
                         join opor in ContextoDeObjs.T_Oportunidad on conopor.co_oportunidad equals opor.co_oportunidad
                         join oporpre in ContextoDeObjs.T_Oportunidad_Presupuesto on opor.co_oportunidad equals oporpre.co_oportunidad
                         join usu in ContextoDeObjs.T_Usuario on opor.co_usuario equals usu.co_usuario
                         join pre in ContextoDeObjs.T_Presupuesto on oporpre.co_presupuesto equals pre.co_presupuesto
                         join cliser in ContextoDeObjs.T_Cliente_Servicio on new { nu_ruc = cli.nu_ruc } equals new { nu_ruc = cliser.nu_ruc_cliente }
                         join ser in ContextoDeObjs.T_Servicio
                               on new { cliser.co_servicio, Column1 = opor.co_servicio }
                           equals new { ser.co_servicio, Column1 = ser.co_servicio }
                         join subser in ContextoDeObjs.T_SubServicio on ser.co_servicio equals subser.T_Servicio.co_servicio
                         join prod in ContextoDeObjs.T_Producto
                               on new { subser.co_subservicio, opor.co_producto }
                           equals new { prod.T_SubServicio.co_subservicio, prod.co_producto }
                         join oporestado in ContextoDeObjs.T_Oportunidad_Estado
                            on opor.co_opor_estado equals oporestado.co_opor_estado
                         where cli.no_sector_economico == no_sector && usu.co_usuario == co_usuario
                         select new
                         {
                             cli.nu_ruc,
                             cli.no_razon_social,
                             co_servicio = (Int32?)ser.co_servicio,
                             ser.no_servicio,
                             co_producto = (Int32?)prod.co_producto,
                             prod.no_producto,
                             co_presupuesto = (Int32?)pre.co_presupuesto,
                             pre.qt_monto_base,
                             no_rubro_comercial = cli.no_principal_CIIU,
                             pre.co_tipo_moneda,
                             Moneda = pre.co_tipo_moneda == 0 ? "Dolares" : pre.co_tipo_moneda == 1 ? "Soles" : "",
                             Esfuerzo = (pre.co_tipo_esfuerzo == 1) ? pre.qt_esfuerzo / 30 : pre.qt_esfuerzo,
                             pre.co_tipo_esfuerzo,
                             Tiempo = pre.co_tipo_esfuerzo == 0 ? "Meses" : pre.co_tipo_esfuerzo == 1 ? "Meses" : "",
                             oporestado.no_opor_estado
                         }).Distinct();

                q = q.OrderByDescending(f4 => f4.qt_monto_base).ThenByDescending(f4 => f4.Esfuerzo);
                s = s.OrderByDescending(f5 => f5.qt_monto_base).ThenByDescending(f5 => f5.Esfuerzo);
                r = r.OrderByDescending(f6 => f6.qt_monto_base).ThenByDescending(f6 => f6.Esfuerzo);

                if (ok) lista = q.ToList().Union(s.ToList().Except(q.ToList()));
                else lista = q.ToList().Union(s.ToList().Except(q.ToList())).Union(r.ToList().Except(q.ToList().Union(s.ToList().Except(q.ToList()))));
            }
            catch (Exception)
            {
                lista = null;
                throw;
            }

            return lista;
        }
        public IEnumerable<Object> GenerarListaOportunidades_DetalleVisita(Int64? nu_ruc, int? co_servicio, int? co_producto, int? co_presupuesto, String no_sector)
        {
            IEnumerable<Object> lista = new List<Object>();
            try
            {
                var q = (from cont in ContextoDeObjs.T_Contacto
                         join cli in ContextoDeObjs.T_Cliente on new { nu_ruc_cliente = cont.T_Cliente.nu_ruc } equals new { nu_ruc_cliente = cli.nu_ruc }
                         join conopor in ContextoDeObjs.T_Contacto_Oportunidad on cont.co_contacto equals conopor.co_contacto
                         join opor in ContextoDeObjs.T_Oportunidad on conopor.co_oportunidad equals opor.co_oportunidad
                         join oporpre in ContextoDeObjs.T_Oportunidad_Presupuesto on opor.co_oportunidad equals oporpre.co_oportunidad
                         join pre in ContextoDeObjs.T_Presupuesto on oporpre.co_presupuesto equals pre.co_presupuesto
                         join cliser in ContextoDeObjs.T_Cliente_Servicio on new { nu_ruc = cli.nu_ruc } equals new { nu_ruc = cliser.nu_ruc_cliente }
                         join ser in ContextoDeObjs.T_Servicio
                               on new { cliser.co_servicio, Column1 = opor.co_servicio }
                           equals new { ser.co_servicio, Column1 = ser.co_servicio }
                         join subser in ContextoDeObjs.T_SubServicio on ser.co_servicio equals subser.T_Servicio.co_servicio
                         join prod in ContextoDeObjs.T_Producto
                               on new { subser.co_subservicio, opor.co_producto }
                           equals new { prod.T_SubServicio.co_subservicio, prod.co_producto }
                         where
                           cli.nu_ruc == nu_ruc &&
                           ser.co_servicio == co_servicio &&
                           prod.co_producto == co_producto &&
                           pre.co_presupuesto == co_presupuesto &&
                           cli.no_sector_economico == no_sector
                         select new
                             {
                                 cont.co_contacto,
                                 cont.no_contacto,
                                 cont.no_cargo,
                                 cont.nu_telef_cel,
                                 conopor.fe_visita,
                                 conopor.fe_hora,
                                 cli.nu_ruc,
                                 opor.co_oportunidad,
                                 no_ruta_acuerdo = (conopor.no_ruta_acuerdo == null) ? "NO" : (conopor.no_ruta_acuerdo == "") ? "NO" : "SI",
                                 ruta_acuerdo = conopor.no_ruta_acuerdo,
                                 conopor.co_cont_opor
                             }).Distinct();

                lista = q.ToList();
            }
            catch (Exception)
            {
                lista = null;
                throw;
            }

            return lista;
        }
        public List<Esfuerzo> HistorialEsfuerzo(long? nu_ruc_cliente, int? co_producto)
        {
            List<Esfuerzo> lista = new List<Esfuerzo>();
            try
            {
                String no_principal_CIIU;
                var a = from c in ContextoDeObjs.T_Cliente
                        where c.nu_ruc == nu_ruc_cliente
                        select c;

                if (a.ToList() == null) no_principal_CIIU = String.Empty;
                else if (a.ToList().Count() == 0) no_principal_CIIU = String.Empty;
                else no_principal_CIIU = a.ToList()[0].no_principal_CIIU;

                if (no_principal_CIIU == String.Empty)
                {
                    var q = (from cont in ContextoDeObjs.T_Contacto
                             join cli in ContextoDeObjs.T_Cliente on new { nu_ruc_cliente = cont.T_Cliente.nu_ruc } equals new { nu_ruc_cliente = cli.nu_ruc }
                             join conopor in ContextoDeObjs.T_Contacto_Oportunidad on cont.co_contacto equals conopor.co_contacto
                             join opor in ContextoDeObjs.T_Oportunidad on conopor.co_oportunidad equals opor.co_oportunidad
                             join oporpre in ContextoDeObjs.T_Oportunidad_Presupuesto on opor.co_oportunidad equals oporpre.co_oportunidad
                             join pre in ContextoDeObjs.T_Presupuesto on oporpre.co_presupuesto equals pre.co_presupuesto
                             join cliser in ContextoDeObjs.T_Cliente_Servicio on new { nu_ruc = cli.nu_ruc } equals new { nu_ruc = cliser.nu_ruc_cliente }
                             join ser in ContextoDeObjs.T_Servicio
                                   on new { cliser.co_servicio, Column1 = opor.co_servicio }
                               equals new { ser.co_servicio, Column1 = ser.co_servicio }
                             join subser in ContextoDeObjs.T_SubServicio on ser.co_servicio equals subser.T_Servicio.co_servicio
                             join prod in ContextoDeObjs.T_Producto
                                   on new { subser.co_subservicio, opor.co_producto }
                               equals new { prod.T_SubServicio.co_subservicio, prod.co_producto }
                             where
                               1 == 1 &&
                              cli.no_principal_CIIU == no_principal_CIIU &&
                              prod.co_producto == co_producto
                             orderby
                               opor.fe_creacion descending
                             select new Esfuerzo
                             {
                                 qt_esfuerzo = pre.qt_esfuerzo,
                                 nu_ruc = cli.nu_ruc,
                                 fe_creacion = opor.fe_creacion,
                                 qt_presupuesto = pre.qt_monto_base
                             }).Take(5);

                    lista = q.ToList();
                }
            }
            catch (Exception)
            {
                lista = null;
                throw;
            }
            return lista;
        }
        public List<T_Actividad> AvanceEsfuerzo(Int64? nu_ruc, int? co_servicio, int? co_producto, int? co_presupuesto)
        {
            List<T_Actividad> lista = new List<T_Actividad>();
            try
            {
                var q = from cont in ContextoDeObjs.T_Contacto
                        join cli in ContextoDeObjs.T_Cliente on new { nu_ruc_cliente = cont.T_Cliente.nu_ruc } equals new { nu_ruc_cliente = cli.nu_ruc }
                        join conopor in ContextoDeObjs.T_Contacto_Oportunidad on cont.co_contacto equals conopor.co_contacto
                        join opor in ContextoDeObjs.T_Oportunidad on conopor.co_oportunidad equals opor.co_oportunidad
                        join oporpre in ContextoDeObjs.T_Oportunidad_Presupuesto on opor.co_oportunidad equals oporpre.co_oportunidad
                        join pre in ContextoDeObjs.T_Presupuesto on oporpre.co_presupuesto equals pre.co_presupuesto
                        join cliser in ContextoDeObjs.T_Cliente_Servicio on new { nu_ruc = cli.nu_ruc } equals new { nu_ruc = cliser.nu_ruc_cliente }
                        join ser in ContextoDeObjs.T_Servicio
                              on new { cliser.co_servicio, Column1 = opor.co_servicio }
                          equals new { ser.co_servicio, Column1 = ser.co_servicio }
                        join subser in ContextoDeObjs.T_SubServicio on ser.co_servicio equals subser.T_Servicio.co_servicio
                        join prod in ContextoDeObjs.T_Producto
                              on new { subser.co_subservicio, opor.co_producto }
                          equals new { prod.T_SubServicio.co_subservicio, prod.co_producto }
                        join crono in ContextoDeObjs.T_Cronograma on opor.co_oportunidad equals crono.T_Oportunidad.co_oportunidad
                        join act in ContextoDeObjs.T_Actividad on new { co_cronograma = crono.co_cronograma } equals new { co_cronograma = (Int32)act.co_cronograma }
                        join rec in ContextoDeObjs.T_Recurso on act.co_actividad equals rec.T_Actividad.co_actividad
                        join per in ContextoDeObjs.T_Persona on rec.co_recurso equals per.T_Recurso.co_recurso
                        join trabper in ContextoDeObjs.T_Trabajador_Persona on per.co_persona equals trabper.co_persona
                        join trab in ContextoDeObjs.T_Trabajador on trabper.co_trabajador equals trab.co_trabajador
                        where 1 == 1 &&
                         cli.nu_ruc == nu_ruc &&
                         ser.co_servicio == co_servicio &&
                         prod.co_producto == co_producto &&
                         pre.co_presupuesto == co_presupuesto
                        select act;

                lista = q.ToList();
            }
            catch (Exception)
            {
                throw;
            }
            return lista;
        }
    }
}
